<script setup>
import Codemirror from "codemirror-editor-vue3"
import "codemirror/mode/clike/clike"
import "codemirror/mode/javascript/javascript"
import { reactive, ref } from 'vue'

const props = defineProps({
  isDrawerOpen: {
    type: Boolean,
    required: true,
  },
  operType: {
    type: Number,
    required: true,
    default: 0,
  },
  currRow: Object,
})

const emit = defineEmits([
  'update:isDrawerOpen',
  'addData',
  'updateData',
])

const operType = ref(props.operType)
const currRow = ref(props.currRow)
const row = currRow.value
const isFormValid = ref(false)
const refForm = ref()
const title = ref(operType.value == 0 ? '新增组件':'更新组件')

const cmpDataHint = ref("JSON数据格式："+ JSON.stringify({ "name": "jack" }))

// 代码编辑器
const cmRef = ref()

const cmOptions = {
  mode: "text/x-java",
}

const onChange = (val, cm) => {
  //console.log(val, cm.getValue())
}

const onInput = val => {
  //console.log(val)
}

const onReady = cm => {
  //console.log(cm.focus())
}

onUnmounted(() => {
  cmRef.value?.destroy()
})

// 表单数据
const id = ref(row.id || '')
const componentId = ref(row.componentId || '')
const componentName = ref(row.componentName || '')
const type = ref(row.type || '')
const script = ref(row.script || '')
const language = ref(row.language || 'java')
const clazz = ref(row.clazz || '')
const fallbackId = ref(row.fallbackId || '')
const cmpPre = ref(row.cmpPre || '')
const cmpFinallyOpt = ref(row.cmpFinallyOpt || '')
const cmpId = ref(row.cmpId || '')
const cmpTag = ref(row.cmpTag || '')
const cmpMaxWaitSeconds = ref(row.cmpMaxWaitSeconds || '')
const cmpTo = ref(row.cmpTo || '')
const cmpDefaultOpt = ref(row.cmpDefaultOpt || '')
const cmpTrueOpt = ref(row.cmpTrueOpt || '')
const cmpFalseOpt = ref(row.cmpFalseOpt || '')
const cmpParallel = ref(row.cmpParallel || '')
const cmpDoOpt = ref(row.cmpDoOpt || '')
const cmpBreakOpt = ref(row.cmpBreakOpt || '')
const cmpDataName = ref(row.cmpDataName || '')
const cmpData = ref(row.cmpData || '')

const clazzShow = ref(false)
const fallbackIdShow = ref(false)
const scriptShow =  ref(false)
const languageShow =  ref(false)
const cmpPreShow = ref(false)
const cmpFinallyOptShow = ref(false)
const cmpIdShow = ref(false)
const cmpTagShow = ref(false)
const cmpMaxWaitSecondsShow = ref(false)
const cmpToShow = ref(false)
const cmpDefaultOptShow = ref(false)
const cmpTrueOptShow = ref(false)
const cmpFalseOptShow = ref(false)
const cmpParallelShow = ref(false)
const cmpDoOptShow = ref(false)
const cmpBreakOptShow = ref(false)
const cmpDataNameShow = ref(false)
const cmpDataShow = ref(false)

// 👉 drawer close
const closeNavigationDrawer = () => {
  emit('update:isDrawerOpen', false)
  nextTick(() => {
    refForm.value?.reset()
    refForm.value?.resetValidation()
  })
}

const onSubmit = () => {
  refForm.value?.validate().then(({ valid }) => {
    if (valid) {
      const data = {
        id: id.value,
        componentId: componentId.value,
        componentName: componentName.value,
        type: type.value,
        script: script.value,
        language: language.value,
        clazz: clazz.value,
        fallbackId: fallbackId.value,
        cmpPre: cmpPre.value,
        cmpFinallyOpt: cmpFinallyOpt.value,
        cmpId: cmpId.value,
        cmpTag: cmpTag.value,
        cmpMaxWaitSeconds: cmpMaxWaitSeconds.value,
        cmpTo: cmpTo.value,
        cmpDefaultOpt: cmpDefaultOpt.value,
        cmpTrueOpt: cmpTrueOpt.value,
        cmpFalseOpt: cmpFalseOpt.value,
        cmpParallel: cmpParallel.value,
        cmpDoOpt: cmpDoOpt.value,
        cmpBreakOpt: cmpBreakOpt.value,
        cmpData: cmpData.value,
        cmpDataName: cmpDataName.value,
      }

      
      if(operType.value == 0){
        emit('addData', data)
      }else{
        emit('updateData', data)
      }
      emit('update:isDrawerOpen', false)
      nextTick(() => {
        refForm.value?.reset()
        refForm.value?.resetValidation()
      })
    }
  })
}



const handleDrawerModelValueUpdate = val => {
  emit('update:isDrawerOpen', val)
}

// 初始化下拉框数据
onMounted(() => {
  changeType(row.type)
  clazzSelect(row.type)
  nodeTypeSelect()
  scriptTypeSelect()
  fallbackListSelect()
  cmpSelect()

  setTimeout(() => {
    cmRef.value?.refresh()
  }, 100)
})

const clazzList = reactive([])

const clazzSelect = async (val) => {
  clazzList.length = 0
  const res = await $ivyApi.post(API_URLS.lfCmpOptions,{type: val})
  clazzList.push(...res.data)
}

const cmpList = reactive([])

const cmpSelect = async () => {
  cmpList.length = 0
  const res = await $ivyApi.post(API_URLS.lfCmpCmpOptions,{})
  cmpList.push(...res.data)
}

const nodeTypeList = reactive([])

const nodeTypeSelect = async () => {
  const res = await $ivyApi.post(API_URLS.lfCmpTypeOptions,{})
  nodeTypeList.push(...res.data)
}

const scriptTypeList = reactive([])

const scriptTypeSelect = async () => {
  const res = await $ivyApi.post(API_URLS.lfCmpScriptOptions,{})
  scriptTypeList.push(...res.data)
}

const fallbackList = reactive([])

const fallbackListSelect = async () => {
  const res = await $ivyApi.post(API_URLS.lfCmpFallbackList,{type: 'fallback'})
  fallbackList.push(...res.data)
}

// 组件类型切换
watch(type, val => {
  changeType(val)
  clazzSelect(val)
})

const shows = [
  clazzShow,
  fallbackIdShow,
  scriptShow,
  languageShow,
  cmpPreShow,
  cmpFinallyOptShow,
  cmpIdShow,
  cmpTagShow,
  cmpMaxWaitSecondsShow, 
  cmpToShow,
  cmpDefaultOptShow,
  cmpTrueOptShow,
  cmpFalseOptShow,
  cmpParallelShow,
  cmpDoOptShow,
  cmpBreakOptShow, 
  cmpDataNameShow,
  cmpDataShow,
]

const showsGD = [cmpIdShow, cmpTagShow, cmpMaxWaitSecondsShow, cmpDataNameShow, cmpDataShow]

const changeType = val => {
  if (val == 'common'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow])
  }else if(val == 'switch'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow, cmpToShow, cmpDefaultOptShow])
  }else if(val == 'if'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow, cmpTrueOptShow, cmpFalseOptShow])
  }else if(val == 'break'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow])
  }else if(val == 'for' || val == 'while'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow, cmpParallelShow, cmpDoOptShow, cmpBreakOptShow])
  }else if(val == 'iterator'){
    changeTypes(showsGD, [clazzShow, cmpPreShow, cmpFinallyOptShow, cmpParallelShow, cmpDoOptShow])
  }else if(val == 'fallback'){
    changeTypes([clazzShow, fallbackIdShow], [])
  }else if(val == 'script'){
    changeTypes(showsGD, [scriptShow, languageShow])
  }else if(val == 'switch_script'){
    changeTypes(showsGD, [scriptShow, languageShow, cmpToShow, cmpDefaultOptShow])
  }else if(val == 'if_script'){
    changeTypes(showsGD, [scriptShow, languageShow, cmpTrueOptShow, cmpFalseOptShow])
  }else if(val == 'for_script' || val == 'while_script'){
    changeTypes(showsGD, [scriptShow, languageShow, cmpParallelShow, cmpDoOptShow, cmpBreakOptShow])
  }else if(val == 'break_script'){
    changeTypes(showsGD, [scriptShow, languageShow])
  }
}

const changeTypes = (showsGD, vals) => {
  const mergedArray = [...showsGD, ...vals]

  shows.forEach(item => {
    item.value = mergedArray.includes(item)
  })
}
</script>

<template>
  <VNavigationDrawer
    temporary
    style="inline-size: 1120px;"
    location="end"
    class="scrollable-content"
    :model-value="props.isDrawerOpen"
    @update:model-value="handleDrawerModelValueUpdate"
  >
    <!-- 👉 Title -->
    <AppDrawerHeaderSection
      :title="title"
      @cancel="closeNavigationDrawer"
    />

    <!-- <PerfectScrollbar :options="{ wheelPropagation: false }"> -->
    <VCard
      flat
      style="overflow-y: scroll;"
    >
      <VCardText>
        <VForm
          ref="refForm"
          v-model="isFormValid"
          @submit.prevent="onSubmit"
        >
          <VRow>
            <VCol cols="12">
              <VTextField
                v-model="componentId"
                :rules="[requiredValidator]"
                class="setting-mb-12"
                label="组件ID"
                clearable
              />
            </VCol>

            <VCol cols="12">
              <VTextField
                v-model="componentName"
                :rules="[requiredValidator]"
                class="setting-mb-12"
                label="组件名称"
                clearable
              />
            </VCol>

            <VCol cols="12">
              <VAutocomplete
                v-model="type"
                label="组件类型"
                :rules="[requiredValidator]"
                :items="nodeTypeList"
                clearable
              />
            </VCol>

            <VCol
              v-show="clazzShow"
              cols="12"
            >
              <VAutocomplete
                v-model="clazz"
                class="setting-mb-12"
                label="spring bean或动态类"
                :items="clazzList"
                clearable
              />
            </VCol>

            <VCol
              v-show="fallbackIdShow"
              cols="12"
            >
              <VAutocomplete
                v-model="fallbackId"
                label="选择降级组件"
                :items="fallbackList"
                item-title="componentName"
                item-value="id"
                clearable
              />
            </VCol>

            <VCol
              v-show="languageShow"
              cols="12"
            >
              <VAutocomplete
                v-model="language"
                label="脚本语言"
                :items="scriptTypeList"
                clearable
              />
            </VCol>

            <VCol
              v-show="scriptShow"
              cols="12"
            >
              <!--
                <VTextarea
                v-model="script"
                class="setting-mb-12"
                label="脚本代码"
                clearable
                counter 
                auto-grow
                rows="10"
                row-height="30"
                /> 
              -->
              <Codemirror
                ref="cmRef"
                v-model:value="script"
                :options="cmOptions"
                border
                height="300"
                width="100%"
                @change="onChange"
                @input="onInput"
                @ready="onReady"
              />
            </VCol>

            <VCol
              v-show="cmpPreShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpPre"
                :items="cmpList"
                class="setting-mb-12"
                label="前置组件"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpFinallyOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpFinallyOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="后置组件"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpToShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpTo"
                multiple
                :items="cmpList"
                class="setting-mb-12"
                label="to"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpDefaultOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpDefaultOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="defaultOpt"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpTrueOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpTrueOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="trueOpt"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpFalseOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpFalseOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="falseOpt"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpParallelShow"
              cols="12"
            >
              <VCheckbox
                v-model="cmpParallel"
                label="是否开启异步循环parallel"
              />
            </VCol>

            <VCol
              v-show="cmpDoOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpDoOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="doOpt"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpBreakOptShow"
              cols="12"
            >
              <VAutocomplete
                v-model="cmpBreakOpt"
                :items="cmpList"
                class="setting-mb-12"
                label="breakOpt"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpIdShow"
              cols="12"
            >
              <VTextField
                v-model="cmpId"
                class="setting-mb-12"
                label="id"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpTagShow"
              cols="12"
            >
              <VTextField
                v-model="cmpTag"
                class="setting-mb-12"
                label="标签"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpMaxWaitSecondsShow"
              cols="12"
            >
              <VTextField
                v-model="cmpMaxWaitSeconds"
                class="setting-mb-12"
                label="超时时间(秒)"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpDataNameShow"
              cols="12"
            >
              <VTextField
                v-model="cmpDataName"
                class="setting-mb-12"
                label="组件参数名称(dataName)"
                clearable
              />
            </VCol>

            <VCol
              v-show="cmpDataShow"
              cols="12"
            >
              <VTextarea
                v-model="cmpData"
                class="setting-mb-12"
                label="组件参数数据"
                :hint="cmpDataHint"
                clearable
                counter
                auto-grow
                rows="5"
                row-height="30"
              />
            </VCol>

            <VCol cols="6">
              <VBtn
                type="submit"
                class="me-3 w-100"
              >
                提交
              </VBtn>
            </VCol>
            <VCol cols="6">
              <VBtn
                class="w-100"
                type="reset"
                variant="tonal"
                color="secondary"
                @click="closeNavigationDrawer"
              >
                取消
              </VBtn>
            </VCol>
          </VRow>
        </VForm>
      </VCardText>
    </VCard>
    <!-- </PerfectScrollbar> -->
  </VNavigationDrawer>
</template>

<style scoped>
.w-100 {
  inline-size: 100%;
}
</style>
